package com.sky.aspect;

import com.sky.autotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 定义自动填充切面
 * 可以这么理解，就是要增强目标方法的类
 *
 */


@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    /**
     * 定义切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && " +
            "@annotation(com.sky.autotation.AutoFill)")
    public void autoFillPointCut(){}
        /**
         * 定义前置通知（在通知中，写发射代码，实现自动填充）
         */
        @Before("autoFillPointCut()")
        public void autoFill(JoinPoint joinPoint){
            log.info("开始进行自动填充...");
            Object[] args = joinPoint.getArgs();
            if (args==null){
                return;
            }

            try {
                //获取目标方法中的参数（Employee Category Dish）
                Object obj=args[0];
                //方法签名
                MethodSignature signature=(MethodSignature) joinPoint.getSignature();
                //获取方法  void insert(Employee employee)
                Method method=signature.getMethod();
                //获取方法上的注解
                AutoFill autoFill = method.getAnnotation(AutoFill.class);
                //获取注解上的值
                OperationType operationType = autoFill.value();

                //我要发射填充四个字段createTime,createUser,updateTime,updateUser
                Class<?> clazz = obj.getClass();
                //获取setUpdateTime方法
                Method setUpdateTime = clazz.getMethod("setUpdateTime", LocalDateTime.class);
                //调用setUpdateTime方法填充值
                setUpdateTime.invoke(obj, LocalDateTime.now());
                //获取字节中的setUpdateUser方法
                Method setUpdateUser = clazz.getMethod("setUpdateUser", Long.class);
                //调用setUpdateUser方法填充值
                setUpdateUser.invoke(obj, BaseContext.getCurrentId());

                //判断对数据库的存在是不是Insert
                if (operationType==OperationType.INSERT){
                    //获取字节中的setCreateTime方法
                    Method setCreateTime = clazz.getMethod("setCreateTime", LocalDateTime.class);
                    //调用setCreateTime方法填充值
                    setCreateTime.invoke(obj, LocalDateTime.now());

                    //获取字节中的setCreateUser方法
                    Method setCreateUser = clazz.getMethod("setCreateUser",Long.class);
                    //调用setCreateUser方法填充值
                    setCreateUser.invoke(obj, BaseContext.getCurrentId());
                }
            }catch (Exception e){
                log.error("自动填充失败：{}",e.getMessage());
            }


        }




}
